vulkan: Make MVP matrix available to vertex shader
authorBenjamin Otte <otte@redhat.com>
Wed, 7 Dec 2016 00:48:31 +0000 (01:48 +0100)
committerBenjamin Otte <otte@redhat.com>
Fri, 9 Dec 2016 17:35:51 +0000 (18:35 +0100)
We use push constants for this.

gsk/gskvulkanpipeline.c
gsk/gskvulkanrenderer.c
gsk/resources/vulkan/blit.vert.glsl
gsk/resources/vulkan/blit.vert.spv

index 012eb8f949ae39225b77f7504f002fa85078d3e7..25e81f5cef57c313e92a78cfcddf1c7263ad336c 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "gskvulkanshaderprivate.h"
 
+#include <graphene.h>
+
 struct _GskVulkanPipeline
 {
   GObject parent_instance;
@@ -93,7 +95,15 @@ gsk_vulkan_pipeline_new (GdkVulkanContext *context,
                                         &(VkPipelineLayoutCreateInfo) {
                                             .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                                             .setLayoutCount = 1,
-                                            .pSetLayouts = &self->descriptor_set_layout
+                                            .pSetLayouts = &self->descriptor_set_layout,
+                                            .pushConstantRangeCount = 1,
+                                            .pPushConstantRanges = (VkPushConstantRange[1]) {
+                                                {
+                                                    .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
+                                                    .offset = 0,
+                                                    .size = sizeof (graphene_matrix_t)
+                                                }
+                                            }
                                         },
                                         NULL,
                                         &self->pipeline_layout);
index 060459b10236348ce6721114ca18fd972a638a5a..e2f959146148435a816deb6403b31521af3fbda0 100644 (file)
@@ -12,6 +12,8 @@
 #include "gskvulkanimageprivate.h"
 #include "gskvulkanpipelineprivate.h"
 
+#include <graphene.h>
+
 typedef struct _GskVulkanTarget GskVulkanTarget;
 
 #ifdef G_ENABLE_DEBUG
@@ -374,14 +376,17 @@ gsk_vulkan_renderer_do_render_commands (GskVulkanRenderer *self,
                                         VkCommandBuffer    command_buffer)
 {
   GskVulkanBuffer *buffer;
+  GdkWindow *window = gsk_renderer_get_window (GSK_RENDERER (self));
+  int width = gdk_window_get_width (window);
+  int height = gdk_window_get_height (window);
   float pts[] = {
-    -1.0, -1.0,  0.0, 0.0,
-     1.0, -1.0,  1.0, 0.0,
-    -1.0,  1.0,  0.0, 1.0,
+    0.0,   0.0,     0.0, 0.0,
+    width, 0.0,     1.0, 0.0,
+    0.0,   height,  0.0, 1.0,
 
-    -1.0,  1.0,  0.0, 1.0,
-     1.0, -1.0,  1.0, 0.0,
-     1.0,  1.0,  1.0, 1.0
+    0.0,   height,  0.0, 1.0,
+    width, 0.0,     1.0, 0.0,
+    width, height,  1.0, 1.0
   };
   guchar *data;
 
@@ -419,6 +424,9 @@ gsk_vulkan_renderer_do_render_commands (GskVulkanRenderer *self,
   gsk_vulkan_buffer_free (buffer);
 }
 
+#define ORTHO_NEAR_PLANE        -10000
+#define ORTHO_FAR_PLANE          10000
+
 static void
 gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self,
                                     VkCommandBuffer    command_buffer,
@@ -426,10 +434,15 @@ gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self,
 {
   GdkRectangle extents;
   GdkWindow *window;
+  int scale_factor, unscaled_width, unscaled_height;
+  graphene_matrix_t modelview, projection, mvp;
 
   window = gsk_renderer_get_window (GSK_RENDERER (self));
   cairo_region_get_extents (gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (GSK_RENDERER (self))),
                             &extents);
+  scale_factor = gsk_renderer_get_scale_factor (GSK_RENDERER (self));
+  unscaled_width = gdk_window_get_width (window) * scale_factor;
+  unscaled_height = gdk_window_get_height (window) * scale_factor;
 
   vkUpdateDescriptorSets (gdk_vulkan_context_get_device (self->vulkan),
                           1,
@@ -457,7 +470,7 @@ gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self,
                             .framebuffer = self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)]->framebuffer,
                             .renderArea = { 
                                 { 0, 0 },
-                                { gdk_window_get_width (window), gdk_window_get_height (window) }
+                                { unscaled_width, unscaled_height }
                             },
                             .clearValueCount = 1,
                             .pClearValues = (VkClearValue [1]) {
@@ -472,8 +485,8 @@ gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self,
                     &(VkViewport) {
                       .x = 0,
                       .y = 0,
-                      .width = gdk_window_get_width (window),
-                      .height = gdk_window_get_height (window),
+                      .width = unscaled_width,
+                      .height = unscaled_height,
                       .minDepth = 0,
                       .maxDepth = 1
                     });
@@ -482,10 +495,25 @@ gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self,
                    0,
                    1,
                    &(VkRect2D) {
-                       { extents.x, extents.y },
-                       { extents.width, extents.height }
+                       { extents.x * scale_factor, extents.y * scale_factor },
+                       { extents.width * scale_factor, extents.height * scale_factor }
                    });
 
+  graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
+  graphene_matrix_init_ortho (&projection,
+                              0, unscaled_width,
+                              0, unscaled_height,
+                              ORTHO_NEAR_PLANE,
+                              ORTHO_FAR_PLANE);
+  graphene_matrix_multiply (&modelview, &projection, &mvp);
+
+  vkCmdPushConstants (command_buffer,
+                      gsk_vulkan_pipeline_get_pipeline_layout (self->pipeline),
+                      VK_SHADER_STAGE_VERTEX_BIT,
+                      0,
+                      sizeof (graphene_matrix_t),
+                      &mvp);
+
   gsk_vulkan_renderer_do_render_commands (self, command_buffer);
 
   vkCmdEndRenderPass (command_buffer);
index 38654054295c834f74c0b84851df7787bb06009e..2522b7e0ef4eaba4ed5ddbbc551cfbb85d77999e 100644 (file)
@@ -3,6 +3,10 @@
 layout(location = 0) in vec2 inPosition;
 layout(location = 1) in vec2 inTexCoord;
 
+layout(push_constant) uniform PushConstants {
+    mat4 mvp;
+} push;
+
 layout(location = 0) out vec2 outTexCoord;
 
 out gl_PerVertex {
@@ -10,6 +14,6 @@ out gl_PerVertex {
 };
 
 void main() {
-  gl_Position = vec4 (inPosition, 0.0, 1.0);
+  gl_Position = push.mvp * vec4 (inPosition, 0.0, 1.0);
   outTexCoord = inTexCoord;
 }
index 66413971d487a02b58404452a55802fad4e79f59..3deee1c8e2a792b01265279178a88a50f7f957a9 100644 (file)
Binary files a/gsk/resources/vulkan/blit.vert.spv and b/gsk/resources/vulkan/blit.vert.spv differ